// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("./utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

// ✅ 是否使用滑动窗口
const useWindow = true;

// ✅ 存放每个 windowSize 的评估结果
const windowStats = [];

// ✅ 包一层循环，尝试不同 windowSize
for (let windowSize = 30; windowSize <= 300; windowSize++) {
  const predictResults = [];

  // ✅ 遍历每一期，从第2期开始
  allValues.forEach((item, index) => {
    const temp = useWindow
      ? allValues.slice(Math.max(0, index - windowSize), index)
      : allValues.slice(0, index);

    if (!temp.length) return;

    const numberIndexMap = {}; // 例如：{ '22': [1, 7, 11] }
    temp.forEach((entry, i) => {
      const num = entry.number;
      if (!numberIndexMap[num]) numberIndexMap[num] = [];
      numberIndexMap[num].push(i);
    });

    const scoreMap = {};
    allNumbers.forEach((num) => {
      const appearIndices = numberIndexMap[num] || [];

      if (appearIndices.length < 2) {
        scoreMap[num] = -Infinity;
        return;
      }

      const intervals = [];
      for (let i = 1; i < appearIndices.length; i++) {
        intervals.push(appearIndices[i] - appearIndices[i - 1]);
      }

      const avgInterval = intervals.reduce((a, b) => a + b, 0) / intervals.length;
      const lastAppearIndex = appearIndices[appearIndices.length - 1];
      const notAppearSince = temp.length - 1 - lastAppearIndex;

      const diff = Math.abs(notAppearSince - avgInterval);
      scoreMap[num] = 1 / (diff + 1e-6);
    });

    const selected = Object.entries(scoreMap)
      .sort((a, b) => b[1] - a[1])
      .map(([num]) => num)
      .slice(0, 32);

    predictResults.push(checkAccuracy(selected, item.number));
  });

  // ✅ 统计当前 windowSize 的表现
  const total = predictResults.length;
  const correct = predictResults.filter(x => x === 1).length;
  const accuracy = total > 0 ? (correct / total * 100).toFixed(2) : 0;

  let maxWrongStreak = 0;
  let currentStreak = 0;
  predictResults.forEach(res => {
    if (res === 0) {
      currentStreak++;
      if (currentStreak > maxWrongStreak) {
        maxWrongStreak = currentStreak;
      }
    } else {
      currentStreak = 0;
    }
  });

  // ✅ 记录结果
  windowStats.push({
    windowSize,
    accuracy: Number(accuracy),
    correct,
    total,
    maxWrongStreak,
  });
}

// ✅ 找出最大连续错误最小的窗口
const best = _.minBy(windowStats, "maxWrongStreak");

// ✅ 输出最佳结果
console.log("🎯 最小连续错误窗口结果：");
console.log(`Window Size: ${best.windowSize}`);
console.log(`最大连续错误次数: ${best.maxWrongStreak}`);
console.log(`准确率: ${best.accuracy}%`);
console.log(`命中次数: ${best.correct}/${best.total}`);

// ✅ 找出准确率最高的窗口
const best2 = _.maxBy(windowStats, "accuracy");

// ✅ 输出最佳准确率窗口
console.log("\n📈 准确率最高窗口结果：");
console.log(`Window Size: ${best2.windowSize}`);
console.log(`准确率: ${best2.accuracy}%`);
console.log(`最大连续错误次数: ${best2.maxWrongStreak}`);
console.log(`命中次数: ${best2.correct}/${best2.total}`);
